const path = require('path')
// 导入清除插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 默认导出插件的类型，因此无需解构插件内部的成员
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

class MyPlugin {
  /**
   * apply 在 webpack 启动时自动被调用
   * 需求：清除 webpack 打包 js 时生成的 bundle.js 中无用注释
   * 时机：生成 bundle.js 之后
   * @param {object} compiler webpack工作的核心对象，包含配置信息，可注册钩子函数
   */
  apply(compiler) {
    console.log('MyPlugin 启动')

    /**
     * @param {string} 插件名称
     * @param {fn} 挂载在钩子上的函数
     */
    compiler.hooks.emit.tap('MyPlugin', compilation => {
      // compilation 对象参数，理解为打包的上下文
      for (const name in compilation.assets) {
        // console.log(name) // 文件名称
        // console.log(compilation.assets[name].source()) // 文件内容
        if (name.endsWith('.js')) {
          const content = compilation.assets[name].source()
          const withoutComments = content.replace(/\/\*\*+\*\*\//g, '')
          compilation.assets[name] = {
            source: () => withoutComments, // 暴露一个 source 方法返回一个新内容
            size: () => withoutComments.length, // 返回内容大小（webpack 内部要求的必须的方法）
          }
        }
      }
    })
  }
}

module.exports = {
  mode: 'none',
  entry: './src/main.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist'),
    // publicPath: 'dist/' // 因为 html 也放入了 dist 中，因此可以去掉此属性
  },
  // 配置开发中的辅助工具（与source map相关）
  devtool: 'source-map',
  devServer: {
    contentBase: ['./public'], // 指定额外的静态资源路径 string or array
    // 添加代理服务配置，其中每个属性即代理规则配置
    proxy: { 
      // key：需要被代理的请求路径前缀，请求地址以/api开始，代理到接口中
      // value：为前缀匹配到的代理规则配置
      '/api': {
        target: 'https://api.github.com',
        pathRewrite: {
          '^/api': '' // 实现代理路径重写，将以 /api 替换为空
        },
        // 默认代理服务器会将实际浏览器请求的主机名，不能使用 localhost:8080
        // 服务器会根据主机名判断请求属于哪个网站，从而指派
        // 值为 ture 表示会以实际代理请求的主机名请求
        changeOrigin: true,
      },
    }
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /.png$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10 * 1024,
          }
        }
      }
    ]
  },
  // 配置插件(大多数插件导出的都是类型，可用类型创建一个实例)
  plugins: [
    new CleanWebpackPlugin(),
    // 用于生成 index.html 文件；传入对象参数，可指定配置选项
    new HtmlWebpackPlugin({
      title: 'Webpack Plugin Sample', // html 标题
      // 以对象的形式设置页面中的元数据标签
      meta: {
        viewport: 'width=device-width'
      },
      template: './src/index.html' // 指定使用的模板
    }),
    // 用于创建 about.html 文件
    new HtmlWebpackPlugin({
      filename: 'about.html'
    }),
    // 指定需要 copy 的文件路径：通配符、文件目录、相对路径 均可
    /* copy-webpack-plugin 5.x 版本可写为如下形式 */
    // new CopyWebpackPlugin([
    //   // 'public/**',
    //   // './public'
    //   'public'
    // ]),
    /* copy-webpack-plugin 6.x 版本需写为如下形式 */
    // 一般上线前才打包，开发阶段不频繁打包
    // new CopyWebpackPlugin({
    //   patterns: [
    //     { from: 'public', to: 'public' }
    //   ]
    // }),
    new MyPlugin()
  ]
}